<?php
/**
 * Timestamp2Behavior class file.
 *
 * @author Jonah Turnquist <poppitypop@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright Copyright &copy; 2008-2011 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

 /**
 * Timestamp2Behavior will automatically fill date and time related atributes.
 *
 * TimestampBehavior will automatically fill date and time related atributes when the active record
 * is created and/or upadated.
 * You may specify an active record model to use this behavior like so:
 * <pre>
 * public function behaviors(){
 *     return array(
 *         'Timestamp2Behavior' => array(
 *             'class' => 'application.components.behaviors.Timestamp2Behavior',
 *             'tsCreateAttribute' => 'timestamp_create_attribute',
 *             'userCreateAttribute' => 'user_create_attribute',
 *             'tsUpdateAttribute' => 'timestamp_update_attribute',
 *             'userUpdateAttribute' => 'user_update_attribute',
 *         )
 *     );
 * }
 * </pre>
 * The {@link tsCreateAttribute} and {@link tsUpdateAttribute} options actually default to 'tsCreated' and 'tsUpdated'
 * respectively, so it is not required that you configure them.  If you do not wish TimestampBehavior
 * to set a timestamp for record update or creation, set the corrisponding attribute option to null.
 *
 * By default, the update attribute is only set on record update.  If you also wish it to be set on record creation,
 * set the {@link setUpdateOnCreate} option to true.
 *
 * Although TimestampBehavior attempts to figure out on it's own what value to inject into the timestamp attribute,
 * you may specify a custom value to use instead via {@link timestampExpression}
 *
 * @author Jonah Turnquist <poppitypop@gmail.com>
 * @author Joachim Werner <joachim.pt.werner@de.gm.com>
 * @version $Id: Timestamp2Behavior.php 3 2011-08-31 07:46:15Z juppwerner@googlemail.com $
 * @package zii.behaviors
 * @since 1.1
 */

class Timestamp2Behavior extends CActiveRecordBehavior {
        // {{{ *** Members ***
    /**
    * @var mixed The name of the attribute to store the creation time.  Set to null to not
    * use a timstamp for the creation attribute.  Defaults to 'create_time'
    */
    public $tsCreateAttribute = 'tsCreated';
    /**
    * @var mixed The name of the attribute to store the creatig user id. Defaults to 'userIdCreated'
    */
    public $userCreateAttribute = 'userIdCreated';
    /**
    * @var mixed The name of the attribute to store the modification time.  Set to null to not
    * use a timstamp for the update attribute.  Defaults to 'update_time'
    */
    public $tsUpdateAttribute = 'tsUpdated';
    /**
    * @var mixed The name of the attribute to store the updating user id. Defaults to 'userIdUpdated'
    */
    public $userUpdateAttribute = 'userIdUpdated';

    /**
    * @var bool Whether to set the update attribute to the creation timestamp upon creation.
    * Otherwise it will be left alone.  Defaults to false.
    */
    public $setUpdateOnCreate = false;

    /**
    * @var mixed The expression that will be used for generating the timestamp.
    * This can be either a string representing a PHP expression (e.g. 'time()'),
    * or a {@link CDbExpression} object representing a DB expression (e.g. new CDbExpression('NOW()')).
    * Defaults to null, meaning that we will attempt to figure out the appropriate timestamp
    * automatically. If we fail at finding the appropriate timestamp, then it will
    * fall back to using the current UNIX timestamp
    */
    public $timestampExpression;

    /**
    * @var array Maps column types to database method
    */
    protected static $map = array(
            'datetime'=>'NOW()',
            'timestamp'=>'NOW()',
            'date'=>'NOW()',
    );
        // }}} 
        // {{{ beforeSave
        /**
     * Responds to {@link CModel::onAfterSave} event.
     * Sets the values of the creation or modified attributes as configured
     *
     * @param CModelEvent $event event parameter
     */
    public function afterSave($event) {
        // New record
        if ($this->getOwner()->getIsNewRecord() && ($this->tsCreateAttribute !== null)) {
            $arTimestamp = new ARTimestamp;
            $arTimestamp->tableName = $this->getOwner()->getTableNamePrepared();
            $arTimestamp->foreignKey = $this->getOwner()->primaryKey;
            $arTimestamp->{$this->tsCreateAttribute} = time();//$this->getTimestampByAttribute($this->tsCreateAttribute);
            $arTimestamp->{$this->userCreateAttribute} = Yii::app()->user->id;
            $arTimestamp->save();
        }
        // Existing record
        if ((!$this->getOwner()->getIsNewRecord() || $this->setUpdateOnCreate) && ($this->tsUpdateAttribute !== null)) {
            $arTimestamp = ARTimestamp::model()->findByAttributes(array('tableName'=>$this->getOwner()->getTableNamePrepared(),'foreignKey'=>$this->getOwner()->primaryKey));
            if(!is_null($arTimestamp)) {
                $arTimestamp->{$this->tsUpdateAttribute} = time(); //$this->getTimestampByAttribute($this->tsUpdateAttribute);
                $arTimestamp->{$this->userUpdateAttribute} = Yii::app()->user->id;
            } else {
                $arTimestamp = new ARTimestamp;
                $arTimestamp->tableName = $this->getOwner()->getTableNamePrepared();
                $arTimestamp->foreignKey = $this->getOwner()->primaryKey;
                $arTimestamp->{$this->tsUpdateAttribute} = $this->getTimestampByAttribute($this->tsUpdateAttribute);
                $arTimestamp->{$this->userUpdateAttribute} = Yii::app()->user->id;
                $arTimestamp->{$this->tsCreateAttribute} = $this->getTimestampByAttribute($this->tsCreateAttribute);
                $arTimestamp->{$this->userCreateAttribute} = Yii::app()->user->id;
            }
            $arTimestamp->save();
        }
    } // }}} 
        // {{{ getTimestampByAttribute
    /**
     * Gets the approprate timestamp depending on the column type $attribute is
     *
     * @param string $attribute $attribute
     * @return mixed timestamp (eg unix timestamp or a mysql function)
     */
    protected function getTimestampByAttribute($attribute) {
        if ($this->timestampExpression instanceof CDbExpression)
            return $this->timestampExpression;
        else if ($this->timestampExpression !== null)
            return @eval('return '.$this->timestampExpression.';');

        $columnType = $this->getOwner()->getTableSchema()->getColumn($attribute)->dbType;
        return $this->getTimestampByColumnType($columnType);
    } // }}} 
        // {{{ getTimestampByColumnType
    /**
     * Returns the approprate timestamp depending on $columnType
     *
     * @param string $columnType $columnType
     * @return mixed timestamp (eg unix timestamp or a mysql function)
     */
    protected function getTimestampByColumnType($columnType) {
        return isset(self::$map[$columnType]) ? new CDbExpression(self::$map[$columnType]) : time();
        } // }}} 
        // {{{ getTimestampData
        public function getTimestampData()
        {
            $result = new StdClass;
            $result->timestamp_created  = $this->getOwner()->{$this->tsCreateAttribute}==0 ? null : $this->getOwner()->{$this->tsCreateAttribute};
            $result->user_created    = $this->getOwner()->{$this->userCreateAttribute}==0 ? null : $this->getOwner()->{$this->userCreateAttribute};
            $result->timestamp_updated  = $this->getOwner()->{$this->tsUpdateAttribute}==0 ? null : $this->getOwner()->{$this->tsUpdateAttribute};
            $result->user_updated    = $this->getOwner()->{$this->userUpdateAttribute}==0 ? null : $this->getOwner()->{$this->userUpdateAttribute};
            return $result;
        } // }}} 
        public function getTsCreated()
        {
            return $this->getOwner()->{$this->tsCreateAttribute}==0 ? null : $this->getOwner()->{$this->tsCreateAttribute};
        }
        // {{{ getTimestampData
        public function getARTimestamp()
        {
            $arTimestamp =  ARTimestamp::model()->findByAttributes(array('tableName'=>$this->getOwner()->getTableNamePrepared(),'foreignKey'=>$this->getOwner()->primaryKey));
            return $arTimestamp;
        } // }}} 
}
/* vim:set ai sw=4 sts=4 et fdm=marker fdc=4: */ 
?>
